#include "stdafx.h"
#include "FFMpegInstance.h"

CFFMpegInstance::CFFMpegInstance(void)
{
#ifndef LINUX_NAS
	///////////////////////////////////////////////////////////
	static HMODULE hmodule = NULL;
	static HMODULE hmodule1 = NULL;
	static HMODULE hmodule2 = NULL;
	static HMODULE hmodule3 = NULL;

	if(hmodule == NULL)
	{
		///////////////////////////////////////////////////////////
		hmodule = LoadLibrary(_T("avcodec-52.dll"));
		f_avcodec_alloc_frame = (g_avcodec_alloc_frame*)GetProcAddress(hmodule, (LPCSTR)"avcodec_alloc_frame");
		f_avcodec_encode_video = (g_avcodec_encode_video*)GetProcAddress(hmodule, (LPCSTR)"avcodec_encode_video");
		f_avcodec_decode_video = (g_avcodec_decode_video*)GetProcAddress(hmodule, (LPCSTR)"avcodec_decode_video");
		f_avcodec_find_encoder = (g_avcodec_find_encoder*)GetProcAddress(hmodule, (LPCSTR)"avcodec_find_encoder");
		f_avcodec_find_decoder = (g_avcodec_find_decoder*)GetProcAddress(hmodule, (LPCSTR)"avcodec_find_decoder");
		f_avcodec_open = (g_avcodec_open*)GetProcAddress(hmodule, (LPCSTR)"avcodec_open");
		f_avpicture_get_size = (g_avpicture_get_size*)GetProcAddress(hmodule, (LPCSTR)"avpicture_get_size");
		f_avpicture_fill = (g_avpicture_fill*)GetProcAddress(hmodule, (LPCSTR)"avpicture_fill");
		f_avcodec_close = (g_avcodec_close*)GetProcAddress(hmodule, (LPCSTR)"avcodec_close");
		f_avcodec_init = (g_avcodec_init*)GetProcAddress(hmodule, (LPCSTR)"avcodec_init");
		f_avcodec_register_all = (g_avcodec_register_all*)GetProcAddress(hmodule, (LPCSTR)"avcodec_register_all");
		f_avcodec_get_context_defaults = (g_avcodec_get_context_defaults*)GetProcAddress(hmodule, (LPCSTR)"avcodec_get_context_defaults");
		f_avcodec_get_context_defaults2 = (g_avcodec_get_context_defaults2*)GetProcAddress(hmodule, (LPCSTR)"avcodec_get_context_defaults2");
		f_avcodec_alloc_context = (g_avcodec_alloc_context*)GetProcAddress(hmodule, (LPCSTR)"avcodec_alloc_context");
		f_avcodec_encode_audio = (g_avcodec_encode_audio*)GetProcAddress(hmodule, (LPCSTR)"avcodec_encode_audio");
		f_avcodec_decode_audio2 = (g_avcodec_decode_audio2*)GetProcAddress(hmodule, (LPCSTR)"avcodec_decode_audio2");
		//f_av_free_packet = (g_av_free_parcket*)  GetProcAddress(hmodule, (LPCSTR)"av_free_packet");
#ifdef _WIN64
		f_av_init_packet = (g_av_init_packet*)GetProcAddress(hmodule, (LPCSTR)"av_init_packet");
#endif


		hmodule1 = LoadLibrary(_T("avformat-52.dll"));
		f_av_register_all = (g_av_register_all*)GetProcAddress(hmodule1, (LPCSTR)"av_register_all");
		f_av_open_input_file = (g_av_open_input_file*)GetProcAddress(hmodule1, (LPCSTR)"av_open_input_file");
		f_dump_format = (g_dump_format*)GetProcAddress(hmodule1, (LPCSTR)"dump_format");
		f_av_read_packet = (g_av_read_packet*)GetProcAddress(hmodule1, (LPCSTR)"av_read_packet");
		f_av_close_input_file = (g_av_close_input_file*)GetProcAddress(hmodule1, (LPCSTR)"av_close_input_file");
		f_av_open_input_file = (g_av_open_input_file*)GetProcAddress(hmodule1, (LPCSTR)"av_open_input_file");
		f_av_find_stream_info = (g_av_find_stream_info*)GetProcAddress(hmodule1, (LPCSTR)"av_find_stream_info");
		f_guess_format = (g_guess_format*)GetProcAddress(hmodule1, (LPCSTR)"guess_format");
		f_av_alloc_format_context = (g_av_alloc_format_context*)GetProcAddress(hmodule1, (LPCSTR)"av_alloc_format_context");
		f_av_write_header = (g_av_write_header*)GetProcAddress(hmodule1, (LPCSTR)"av_write_header");
		f_av_metadata_set = (g_av_metadata_set*)GetProcAddress(hmodule1, (LPCSTR)"av_metadata_set2");
		f_av_write_frame = (g_av_write_frame*)GetProcAddress(hmodule1, (LPCSTR)"av_write_frame");
		f_av_set_parameters = (g_av_set_parameters*)GetProcAddress(hmodule1, (LPCSTR)"av_set_parameters");
		f_av_new_stream = (g_av_new_stream*)GetProcAddress(hmodule1, (LPCSTR)"av_new_stream");
		f_url_fopen = (g_url_fopen*)GetProcAddress(hmodule1, (LPCSTR)"url_fopen");
		f_url_fclose = (g_url_fclose*)GetProcAddress(hmodule1, (LPCSTR)"url_fclose");
#ifndef _WIN64
		f_av_init_packet = (g_av_init_packet*)GetProcAddress(hmodule1, (LPCSTR)"av_init_packet");	
#endif
		f_av_write_trailer = (g_av_write_trailer*)GetProcAddress(hmodule1, (LPCSTR)"av_write_trailer");
		f_av_oformat_next = (g_av_oformat_next*)GetProcAddress(hmodule1, (LPCSTR)"av_oformat_next");

		f_av_interleaved_write_frame = (g_av_interleaved_write_frame*) GetProcAddress(hmodule1, (LPCSTR)"av_interleaved_write_frame");
		f_av_read_frame = (g_av_read_frame*) GetProcAddress(hmodule1, (LPCSTR)"av_read_frame");
		f_av_seek_frame = (g_av_seek_frame*) GetProcAddress(hmodule1, (LPCSTR)"av_seek_frame");
		


#ifdef _WIN64
		hmodule2 = LoadLibrary(_T("avutil-50.dll"));
#else
		hmodule2 = LoadLibrary(_T("avutil-49.dll"));
#endif
		f_av_free = (g_av_free*)GetProcAddress(hmodule2, (LPCSTR)"av_free");
		f_av_rescale_q = (g_av_rescale_q*)GetProcAddress(hmodule2, (LPCSTR)"av_rescale_q");
		f_av_log_set_callback = (g_av_log_set_callback*)GetProcAddress(hmodule2, (LPCSTR)"av_log_set_callback");
		f_av_malloc = (g_av_malloc*)GetProcAddress(hmodule2, (LPCSTR)"av_malloc");

		hmodule3 = LoadLibrary(_T("swscale-0.dll"));
		f_sws_getContext = (g_sws_getContext*)GetProcAddress(hmodule3, (LPCSTR)"sws_getContext");
		f_sws_scale = (g_sws_scale*)GetProcAddress(hmodule3, (LPCSTR)"sws_scale");
		f_sws_freeContext = (g_sws_freeContext*)GetProcAddress(hmodule3, (LPCSTR)"sws_freeContext");
		/////////////////////////////////////////////////////////////
	}
#endif

	InitCritical(g_lock);

	f_avcodec_init();

	// Register all codecs
	f_avcodec_register_all();
	f_av_register_all();
}

CFFMpegInstance::~CFFMpegInstance(void)
{
	DeleteCritical(g_lock);
}

void CFFMpegInstance::f_av_free_packet(AVPacket *pkt)
{
	if (pkt)
	{
		if (pkt->destruct) 
			pkt->destruct(pkt);
		pkt->data = NULL; 
		pkt->size = 0;
	}
}

void CFFMpegInstance::f_lock()
{
	EnterCritical(g_lock);
}

void CFFMpegInstance::f_unlock()
{
	LeaveCritical(g_lock);
}
